/*
 * (c) ralfoide, http://gamez.googlecode.com/, 2008
 * Project: gamez/packer
 * License TBD
 */

package com.alfray.gamez.packer;

import static org.junit.Assert.*;

import java.io.InputStream;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import com.alfray.gamez.packer.ColladaReader.InputInfo;
import com.alfray.gamez.util.NodesIterator;

public class ColladaReaderTest {

	private Document mDocBox1;

	//-------------------------------------------

	@Before
	public void setUp() throws Exception {
		InputStream is = this.getClass().getResourceAsStream("testdata/box1.dae");
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		mDocBox1 = builder.parse(is);
		assertNotNull(mDocBox1);
	}

	@After
	public void tearDown() throws Exception {
	}

	//-------------------------------------------
	
	@Test
	public void testParseString() {
		URL url = this.getClass().getResource("testdata/box1.dae");
		assertEquals(true, ColladaReader.parse(url.getPath()));
	}

	@Test
	public void testParseString_emptyString() {
		assertEquals(false, ColladaReader.parse(""));
	}

	@Test
	public void testParseString_invalidFilename() {
		URL url = this.getClass().getResource("testdata/box1.dae");
		assertEquals(false, ColladaReader.parse(url.getPath() + "_not-a-valid-filename"));
	}

	@Test
	public void testParseString_nullString() {
		assertEquals(false, ColladaReader.parse((String)null));
	}

	//-------------------------------------------

	@Test
	public void testParseInputStream() {
		InputStream is = this.getClass().getResourceAsStream("testdata/box1.dae");
		assertEquals(true, ColladaReader.parse(is));
	}

	@Test(expected=IllegalArgumentException.class)
	public void testParseInputStream_nullInputStream() {
		ColladaReader.parse((InputStream)null);
	}

	//-------------------------------------------

	@Test
	public void testProcess() {
		MockColladaReader m = new MockColladaReader(null);
		assertEquals(false, m.process());
	}

	@Test
	public void testLoadInputSource() {
		MockColladaReader m = new MockColladaReader(mDocBox1);
		Node n = m.getElement(m.getMockDoc(), "/COLLADA/library_geometries/geometry[@id='mesh1-geometry']/mesh/source[@id='mesh1-geometry-position']");
		InputInfo ii = new ColladaReader.InputInfo(ColladaReader.InputInfo.Semantic.VERTEX, "mesh1-geometry-position", 0);
		assertTrue(m.loadInputSource(ii, n));
		assertEquals(3, ii.getSourceStride());
		assertEquals(24, ii.getSourceValues().length);
		float[] expected = new float[] {
				1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 
				1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 
				1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f
				};
		assertEquals(24, expected.length);
		for (int i = 0; i < 24; i++) {
			assertEquals(expected[i], ii.getSourceValues()[i], 1e-6);
		}
	}
	
	//-------------------------------------------

	@Test
	public void testGetAttr() {
		MockColladaReader m = new MockColladaReader(mDocBox1);
		assertEquals("#SketchUpScene",
				m.getAttr(m.getMockDoc(), "/COLLADA/scene/instance_visual_scene/@url"));
	}

	@Test
	public void testGetUrlId() {
		MockColladaReader m = new MockColladaReader(mDocBox1);
		assertEquals("SketchUpScene",
				m.getUrlId(m.getMockDoc(), "/COLLADA/scene/instance_visual_scene/@url"));
	}

	//-------------------------------------------

	@Test
	public void testGetElement() {
		MockColladaReader m = new MockColladaReader(mDocBox1);
		Node n = m.getElement(m.getMockDoc(), "/COLLADA/scene/instance_visual_scene");
		assertNotNull(n);
		assertEquals("#SketchUpScene", m.getAttr(n, "@url"));
	}

	//-------------------------------------------

	@Test
	public void testGetElements() {
		MockColladaReader m = new MockColladaReader(mDocBox1);
		
		NodesIterator nodes = m.getElements(m.getMockDoc(),
				"/COLLADA/library_visual_scenes/visual_scene[@id='SketchUpScene']//node[instance_geometry]");
		assertNotNull(nodes);
		assertNotNull(nodes.getNodeList());
		assertEquals(2, nodes.getNodeList().getLength());

		assertEquals("mesh1", m.getAttr(nodes.next(), "@id"));
		assertEquals("mesh2", m.getAttr(nodes.next(), "@id"));
	}

	//-------------------------------------------
	/** A mock ColladaReader on which we can control the input document */
	private class MockColladaReader extends ColladaReader {

		private Document mMockDoc;

		MockColladaReader(Document doc) {
			super(doc);
			mMockDoc = doc;
		}
		
		public Document getMockDoc() {
			return mMockDoc;
		}
	}

}
